package com.util;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * @Description  一个标识接口 https://mp.weixin.qq.com/s/XyOEDNImn-FTtpQBDoKeEw
 * 实现RandomAccess接口的List可以通过for循环来遍历数据比使用iterator遍历数据更高效，未实现RandomAccess接口的List可以通过iterator遍历数据比使用for循环来遍历数据更高效。
 * @Author away
 * @Version V1.0.0
 * @Since 1.0
 * @Date 2019/6/21
 */
public class RandomAccessDemo {

    private static Long CIRCLE = 10000L;

    /**
     * ArrayList实现了 RandomAccess 接口，LinkedList 未实现RandomAccess 在 Collections 源码中 判断list是否是RandomAccess的实例，如果是，则执行indexedBinarySearch方法，如果不是，则执行iteratorBinarySearch方法。
     * 所以 LinkedList 使用get（0） 这种随机访问，走的是 iteratorBinarySearch 比较慢。
     * forearch 其实是iterator 的语法糖，性能基本没差。
     * @param args
     */
    public static void main(String[] args) {
        long linkedListIndexedTime = linkedListIndexed();
        long linkedListIteratorTime = linkedListIterator();
        long linkedListForeachTime = linkedListForeach();

        long arrayListIndexedTime = arrayListIndexed();
        long arrayListIteratorTime = arrayListIterator();
        long arrayListForearchime = arrayListForearch();


        System.out.println("测试ArrayList通过for遍历所消耗时间：" + arrayListIndexedTime);
        System.out.println("测试ArrayList通过iterator遍历所消耗时间：" + arrayListIteratorTime);
        System.out.println("测试ArrayList通过forearch遍历所消耗时间：" + arrayListForearchime);
        System.out.println();
        System.out.println("测试LinkedList通过for遍历所消耗时间：" + linkedListIndexedTime);
        System.out.println("测试LinkedList通过iterator遍历所消耗时间：" + linkedListIteratorTime);
        System.out.println("测试LinkedList通过forearch遍历所消耗时间：" + linkedListForeachTime);

    }

    //测试ArrayList通过for遍历所消耗时间
    public static long arrayListIndexed() {
        List<Integer> arrayList = new ArrayList();
        for (int i = 0; i < CIRCLE; i++) {
            arrayList.add(i);
        }
        //记录开始时间

        long startTime = System.nanoTime();
        for (int i = 0; i < arrayList.size(); i++) {
            System.out.println(arrayList.get(i));
        }
        //记录结束时间
        long endTime = System.nanoTime();
        //遍历消耗时间
        long resultTime = endTime - startTime;
        return resultTime;
    }

    //测试ArrayList通过iterator遍历所消耗时间
    public static long arrayListIterator() {
        List<Integer> arrayList = new ArrayList();
        for (int i = 0; i < CIRCLE; i++) {
            arrayList.add(i);
        }
        //记录开始时间
        long startTime = System.nanoTime();
        Iterator<Integer> iterator = arrayList.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        //记录结束时间
        long endTime = System.nanoTime();
        //遍历消耗时间
        long resultTime = endTime - startTime;
        return resultTime;
    }


    //测试ArrayList通过forearch遍历所消耗时间
    public static long arrayListForearch() {
        List<Integer> arrayList = new ArrayList();
        for (int i = 0; i < CIRCLE; i++) {
            arrayList.add(i);
        }
        //记录开始时间
        long startTime = System.nanoTime();
        for (Integer i : arrayList) {
            System.out.println( i);
        }
        //记录结束时间
        long endTime = System.nanoTime();
        //遍历消耗时间
        long resultTime = endTime - startTime;
        return resultTime;
    }

    //测试LinkedList通过for遍历所消耗时间
    public static long linkedListIndexed() {
        List<Integer> linkedList = new LinkedList();
        for (int i = 0; i < CIRCLE; i++) {
            linkedList.add(i);
        }
        //记录开始时间
        long startTime = System.nanoTime();
        for (int i = 0; i < linkedList.size(); i++) {
            System.out.println( linkedList.get(i));
        }
        //记录结束时间
        long endTime = System.nanoTime();
        //遍历消耗时间
        long resultTime = endTime - startTime;
        return resultTime;
    }

    //测试LinkedList通过iterator遍历所消耗时间
    public static long linkedListIterator() {
        List<Integer> linkedList = new LinkedList();
        for (int i = 0; i < CIRCLE; i++) {
            linkedList.add(i);
        }
        //记录开始时间
        long startTime = System.nanoTime();
        Iterator<Integer> iterator = linkedList.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        //记录结束时间
        long endTime = System.nanoTime();
        //遍历消耗时间
        long resultTime = endTime - startTime;
        return resultTime;
    }

    //测试LinkedList通过foreach遍历所消耗时间
    public static long linkedListForeach() {
        List<Integer> linkedList = new LinkedList();
        for (int i = 0; i < CIRCLE; i++) {
            linkedList.add(i);
        }
        //记录开始时间
        long startTime = System.nanoTime();
        for (Integer i : linkedList) {
            System.out.println( i);
        }
        //记录结束时间
        long endTime = System.nanoTime();
        //遍历消耗时间
        long resultTime = endTime - startTime;
        return resultTime;
    }
}
